package com.todod.base.module.base.util;


//import net.lingala.zip4j.model.ZipParameters;
//import net.lingala.zip4j.util.Zip4jConstants;
//import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.tools.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileZipUtils {

    private static Logger logger = LoggerFactory.getLogger(FileZipUtils.class);

//    public static void main(String[] args) {
//        // 解压
////        unZipFiles("D:\\test\\unzip\\test.zip","D:\\test\\");
//        // 压缩
////        zipFiles("D:\\test\\zip\\","D:\\test\\unzip\\test.zip");
//        // 加密
////        zipEncrypt("C:\\Users\\Administrator\\Desktop\\脱敏测试压缩.zip","C:\\Users\\Administrator\\Desktop\\脱敏测试压缩加密.zip","123");
//    }

    /**
     * 压缩文件目录
     * @param source 源文件目录（单个文件和多层目录）
     * @param destit 目标目录
     */
    public static void zipFiles(String source,String destit) {
        File file = new File( source );
        ZipOutputStream zipOutputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream( destit );
            zipOutputStream = new ZipOutputStream( fileOutputStream );
            if (file.isDirectory()) {
                directory( zipOutputStream, file, "" );
            }
            logger.debug("文件压缩成功!");
        } catch (Exception e) {
            logger.debug("文件压缩失败!");
            e.printStackTrace();
        } finally {
            try {
                zipOutputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 解压缩ZIP文件，将ZIP文件里的内容解压到descFileName目录下
     * @param zipFileName 需要解压的ZIP文件
     * @param descFileName 目标目录
     */
    public static boolean unZipFiles(String zipFileName, String descFileName) {
        String descFileNames = descFileName;
        if (!descFileNames.endsWith(File.separator)) {
            descFileNames = descFileNames + File.separator;
        }
        try {
            // 根据ZIP文件创建ZipFile对象
            ZipFile zipFile = new ZipFile(zipFileName);
            org.apache.tools.zip.ZipEntry entry = null;
            String entryName = null;
            String descFileDir = null;
            byte[] buf = new byte[4096];
            int readByte = 0;
            // 获取ZIP文件里所有的entry
            @SuppressWarnings("rawtypes")
            Enumeration enums = zipFile.getEntries();
            // 遍历所有entry
            while (enums.hasMoreElements()) {
                entry = (org.apache.tools.zip.ZipEntry) enums.nextElement();
                // 获得entry的名字
                entryName = entry.getName();
                descFileDir = descFileNames + entryName;
                if (entry.isDirectory()) {
                    // 如果entry是一个目录，则创建目录
                    new File(descFileDir).mkdirs();
                    continue;
                } else {
                    // 如果entry是一个文件，则创建父目录
                    new File(descFileDir).getParentFile().mkdirs();
                }
                File file = new File(descFileDir);
                // 打开文件输出流
                OutputStream os = new FileOutputStream(file);
                // 从ZipFile对象中打开entry的输入流
                InputStream is = zipFile.getInputStream(entry);
                while ((readByte = is.read(buf)) != -1) {
                    os.write(buf, 0, readByte);
                }
                os.close();
                is.close();
            }
            zipFile.close();
            logger.debug("文件解压成功!");
            return true;
        } catch (Exception e) {
            logger.debug("文件解压失败：" + e.getMessage());
            return false;
        }
    }



//
//    /**
//     * zip包加密
//     * @param filePath 要加密的zip文件
//     * @param savePath 加密后的zip文件
//     * @param password 密码
//     * @return
//     */
//    private static boolean zipEncrypt(String filePath, String savePath, String password) {
//        String zipFolder = FilenameUtils.getFullPath(filePath) + File.separator +FilenameUtils.getBaseName(savePath);
//        logger.debug("解压文件:{}",filePath);
//        logger.debug("解压目录:{}",zipFolder);
//        try {
//            FileZipUtils.unZipFiles(filePath,zipFolder);
//            net.lingala.zip4j.core.ZipFile zipFile = new net.lingala.zip4j.core.ZipFile(savePath);
//            //设置压缩文件参数
//            ZipParameters parameters = new ZipParameters();
//            //设置压缩方法
//            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
//            //设置压缩级别
//            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//            //是否加密
//            parameters.setEncryptFiles(true);
//            //设置密码
//            parameters.setPassword(password);
//            //加密方法
//            parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
//            //设置aes加密强度
//            parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//            //添加文件到压缩文件
//            zipFile.addFolder(zipFolder,parameters);
//            FileZipUtils.deleteFolder(zipFolder);
//            logger.debug("加密成功!");
//            return true;
//        } catch (Exception e) {
//            e.printStackTrace();
//            logger.error("对【{}】文件加密处理异常:{}",filePath,e.getMessage());
//            return false;
//        }
//    }

    /**
     * 递归压缩目录结构
     * @param zipOutputStream
     * @param file
     * @param parentFileName
     */
    private static void directory(ZipOutputStream zipOutputStream,File file,String parentFileName){
        File[] files = file.listFiles();
        String parentFileNameTemp = null;
        for (File fileTemp: files) {
            parentFileNameTemp =  StringUtils.isEmpty(parentFileName)?fileTemp.getName():parentFileName+"/"+fileTemp.getName();
            if(fileTemp.isDirectory()){
                directory(zipOutputStream,fileTemp, parentFileNameTemp);
            }else{
                zipFile(zipOutputStream,fileTemp,parentFileNameTemp);
            }
        }
    }

    private static void zipFile(ZipOutputStream zipOutputStream, File file, String parentFileName){
        FileInputStream in = null;
        try {
            ZipEntry zipEntry = new ZipEntry( parentFileName);
            zipOutputStream.putNextEntry( zipEntry );
            in = new FileInputStream( file);
            int len;
            byte [] buf = new byte[8*1024];
            while ((len = in.read(buf)) != -1){
                zipOutputStream.write(buf, 0, len);
            }
            zipOutputStream.closeEntry(  );
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try{
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 删除目录
    public static boolean deleteFolder(String folderPath){
        File file = new File(folderPath);
        if (file.isDirectory()){
            File[] files = file.listFiles();
            for (File file1 : files) {
                if (file1.isFile()){
                    file1.delete();
                }else if (file1.isDirectory()){
                    deleteFolder(file1.getAbsolutePath());
                }
            }
            file.delete();
        }
        return file.exists() ? false : true;
    }
}



